package cn.lavenir.fyai.rag.stream;

import dev.langchain4j.agent.tool.P;
import dev.langchain4j.agent.tool.Tool;
import dev.langchain4j.agent.tool.ToolMemoryId;
import org.springframework.stereotype.Component;

/**
 * @BelongsProject: langchain4j
 * @BelongsPackage: com.xiang.langchain4j.tool
 * @Author: xj
 * @CreateTime: 2025-06-14  21:58
 * @Description:
 * 大语言模型本身并不擅长数学运算。如果应用场景中偶尔会涉及到数学计算，我们可以为他提供
 * 一个 “数学工具”。当我们提出问题时，大语言模型会判断是否使用某个工具。
 *
 * 用 @Tool 注解的方法：
 * 既可以是静态的，也可以是非静态的；
 * 可以具有任何可见性（公有、私有等）。
 *
 * @Tool 注解有两个可选字段：
 * name（工具名称）：工具的名称。如果未提供该字段，方法名会作为工具的名称。
 * value（工具描述）：工具的描述信息。
 * 根据工具的不同，即使没有任何描述，大语言模型可能也能很好地理解它（例如， add(a, b) 就很直
 * 观），但通常最好提供清晰且有意义的名称和描述。这样，大语言模型就能获得更多信息，以决定是否
 * 调用给定的工具以及如何调用。
 * @P 注解
 * 方法参数可以选择使用 @P 注解进行标注。
 * @P 注解有两个字段：
 * value：参数的描述信息，这是必填字段。
 * required：表示该参数是否为必需项，默认值为 true ，此为可选字段。
 *
 * 如果你的AIService方法中有一个参数使用 @MemoryId 注解，那么你也可以使用 @ToolMemoryId 注解
 * @Tool 方法中的一个参数。提供给AIService方法的值将自动传递给 @Tool 方法。如果你有多个用户，
 * 或每个用户有多个聊天记忆，并且希望在 @Tool 方法中对它们进行区分，那么这个功能会很有用
 * @Version: 1.0
 */

@Component
public class CalculatorTools {

    @Tool(name = "加法", value = "返回两个参数相加之和")
    double sum(
            @ToolMemoryId int memoryId,
            @P(value="加数1", required = true) double a,
            @P(value="加数2", required = true) double b) {
        System.out.println("调用加法运算 " + memoryId);
        return a + b;
    }
    @Tool(name = "平方根", value = "返回给定参数的平方根")
    double squareRoot(
            @ToolMemoryId int memoryId, double x) {
        System.out.println("调用平方根运算 " + memoryId);
        return Math.sqrt(x);
    }

    @Tool(name = "创建派单", value = "帮用户创建派单信息，需要用户提供站点编码，和施工队长，派单时间")
    String createWork(
            @ToolMemoryId int memoryId, String  siteCode, String leader, String workTime) {
        System.out.println("创建派单 " + memoryId);
        System.out.println("站点编码：" + siteCode);
        System.out.println("施工队长：" + leader);
        System.out.println("派单时间：" + workTime);
        //拼接成一句话
        String workInfo = "站点编码：" + siteCode + "，施工队长：" + leader + "，派单时间：" + workTime;
        return workInfo;
    }
}


